package cc.rengu.igas.channel.cups.biz.impl;

import cc.rengu.igas.channel.cups.facade.base.BaseRequest;
import cc.rengu.igas.channel.cups.facade.base.BaseResponse;
import cc.rengu.igas.channel.cups.facade.result.Result;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;

/**
 * ESB 透传调用
 *
 * @author fangmingwei
 * @date 2020/11/26/16:09
 */
@SuppressWarnings({"unchecked", "rawtypes", "AlibabaLowerCamelCaseVariableNaming"})
public class CupsCommImpl<Q extends BaseRequest, P extends BaseResponse> extends CupsCommImplTP<Q, P> {

    protected Result<P> callService(Q request) throws Exception {
        /* 获取上一层函数名称
         * 1.用于调用同名radp服务
         * 2.用于反射获取返回值的Class，用于异常时创建返回对象
         */
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.INST_ID, request.getHeader().getInstId());
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        Method[] methods = getClass().getMethods();
        Method method = null;
        for (Method m : methods) {

            if (m.getName().equals(methodName)) {
                method = m;
                break;
            }
        }
        if (null == method) {
            throw new Exception(getClass().getName() + "类无此方法名：" + methodName);
        }
        //获取函数返回值里泛型 T 的Class     Result<T>
        ParameterizedType retType = (ParameterizedType) method.getAnnotatedReturnType().getType();
        Class retTClass = (Class) retType.getActualTypeArguments()[0];

        //方法名按照标准驼峰方式，首字母小写
        String serviceName = methodName.substring(0, 1).toUpperCase() + methodName.substring(1);

        return go(request, serviceName, retTClass);
    }

    protected Result<P> callService(Q request, String radpServiceName) throws Exception {
        /* 获取上一层函数名称
         * 1.用于调用同名radp服务
         * 2.用于反射获取返回值的Class，用于异常时创建返回对象
         */
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();

        //获取函数返回值里泛型 T 的Class     Result<T>
        Method m = getClass().getMethod(methodName, request.getClass());
        ParameterizedType retType = (ParameterizedType) m.getAnnotatedReturnType().getType();
        Class retTClass = (Class) retType.getActualTypeArguments()[0];

        if (StringUtil.isEmptyOrNull(radpServiceName)) {
            //方法名按照标准驼峰方式，首字母小写
            String serviceName = methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
            return go(request, serviceName, retTClass);
        } else {
            return go(request, radpServiceName, retTClass);
        }
    }

}
